package com.pbase.data.http.listener;

import android.net.ParseException;

import com.blankj.utilcode.util.Utils;
import com.google.gson.JsonParseException;
import com.pbase.R;
import com.pbase.data.http.DataState;
import com.pbase.tools.Logger;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import io.reactivex.rxjava3.observers.DisposableObserver;
import retrofit2.HttpException;

/**
 * 请求监听器，先做一层解析
 * 简化参考 -- 屏蔽进度回调参考
 * public abstract class OnDataRequestListener extends
 *  OnDataRequestListenerWithProgress<CurrentRsponseResult> {
 *      public abstract void onRequestDataSuccess(
 *                  CurrentRsponseResult responseResult);
 *      @Override
 *      public void inProgress(float progress, long total) {
 *      }
 * }
 */
public abstract class OnDataRequestListenerWithProgress<T extends BaseResponseResult> extends DisposableObserver<String> {
    private T responseResult;
    public OnDataRequestListenerWithProgress(T t ) {
        this.responseResult = t;
    }

    public abstract void onRequestDataSuccess(
            T responseResult);

    public abstract void done();

    public abstract void onRequestDataFailed(int code, String msg);

    public abstract void inProgress(float progress, long total);


    @Override
    public void onError(Throwable e) {//Throwable类是整个异常体系类的“父级类”
        e.printStackTrace();
        // SocketTimeoutException , ConnectException

        if (e instanceof HttpException) {
            HttpException httpException = (HttpException) e;
            int code = httpException.code();
            Logger.d(getClass(), "http error code:" + code);
            if (code == 502 || code == 404) {
                onRequestDataFailed(DataState.ERR_SERVER, Utils.getApp()
                        .getString(R.string.data_err_codeerror, code));
            } else {
                onRequestDataFailed(DataState.ERR_NETWORK, Utils.getApp()
                        .getString(R.string.data_err_network));
            }
        } else if (e instanceof ConnectException || e instanceof SocketTimeoutException
                || e instanceof UnknownHostException) {
            onRequestDataFailed(DataState.ERR_NETWORK, Utils.getApp()
                    .getString(R.string.data_err_network));
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {
            onRequestDataFailed(DataState.ERR_SERVER, Utils.getApp()
                    .getString(R.string.data_err_server));
        } else {
            onRequestDataFailed(DataState.ERR_DATA,
                    Utils.getApp().getString(R.string.data_err_data));
        }
        done();
    }

    @Override
    public void onNext(String response) {
        Logger.d(getClass(), "http response:" + response);
        try {
            JSONObject object = new JSONObject(response);
            responseResult.analyJsonObject(object);
            if (!responseResult.isSuccess()) {
                onRequestDataFailed(responseResult.getCode(), responseResult.getMessage());
                done();
                return;
            }
            onRequestDataSuccess(  responseResult);
            done();
        } catch (JSONException e) {
            try {
                //防止直接甩JSONArray的情况，收到JSONArray只要解析不抛异常，都认为是成功
                JSONArray jsonArray = new JSONArray(response);
                responseResult.analyJsonObject(jsonArray);
                responseResult.setCode(DataState.REQUESE_SUCCESS);
                if (!responseResult.isSuccess()) {
                    onRequestDataFailed(responseResult.getCode(), responseResult.getMessage());
                    done();
                    return;
                }
                onRequestDataSuccess(  responseResult);
                done();
            } catch (JSONException e1) {
                e1.printStackTrace();
                onRequestDataFailed(DataState.ERR_DATA,
                        Utils.getApp().getString(R.string.data_err_data));
            }
        }
    }


    @Override
    public void onComplete() {
        done();
    }

    //监听进度的改变
    public void onProgressChange(long bytesWritten, long contentLength) {
        float progress = (bytesWritten * 100 / contentLength) / 100.f;
        inProgress(progress, contentLength);
    }
}
